<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <meta name="description" content="异步处理Celery为什么要使用异步首先，我们要知道计算机的处理分为两种，CPU处理和IO处理。一般来说，处理一个任务，需要CPU和IO相互协调。
CPU的处理速度远远快于IO的，所以当一个任务的CPU处理部分完成后，还需要等待IO的完成。这个等待的过程也就是进程阻塞。进程占着CPU空等没活干。
而" />
  

  
  
  
  
  
  
  <title>Celery | 南辞的技术博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="异步处理Celery为什么要使用异步首先，我们要知道计算机的处理分为两种，CPU处理和IO处理。一般来说，处理一个任务，需要CPU和IO相互协调。 CPU的处理速度远远快于IO的，所以当一个任务的CPU处理部分完成后，还需要等待IO的完成。这个等待的过程也就是进程阻塞。进程占着CPU空等没活干。 而异步就是把进程在等待过程中占用的CPU释放掉，让它去处理其他的东西。那正在处理的IO怎么办？系统提供">
<meta property="og:type" content="article">
<meta property="og:title" content="Celery">
<meta property="og:url" content="https://yanlidoushikeke.gitee.io/myhexo/2021/03/10/Celery/index.html">
<meta property="og:site_name" content="南辞的技术博客">
<meta property="og:description" content="异步处理Celery为什么要使用异步首先，我们要知道计算机的处理分为两种，CPU处理和IO处理。一般来说，处理一个任务，需要CPU和IO相互协调。 CPU的处理速度远远快于IO的，所以当一个任务的CPU处理部分完成后，还需要等待IO的完成。这个等待的过程也就是进程阻塞。进程占着CPU空等没活干。 而异步就是把进程在等待过程中占用的CPU释放掉，让它去处理其他的东西。那正在处理的IO怎么办？系统提供">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2021-03-10T13:35:14.000Z">
<meta property="article:modified_time" content="2021-03-10T13:42:22.770Z">
<meta property="article:author" content="南辞">
<meta name="twitter:card" content="summary">
  
  
    <link rel="icon" href="/tefuir/css/images/favicon.ico">
  
  
<link rel="stylesheet" href="/tefuir/css/style.css">

  

  
  <!-- baidu webmaster push -->
  <script src='//push.zhanzhang.baidu.com/push.js'></script>
<meta name="generator" content="Hexo 5.2.0"><link rel="alternate" href="/tefuir/atom.xml" title="南辞的技术博客" type="application/atom+xml">
</head>
<body class="home blog custom-background custom-font-enabled single-author">
  <div id="page" class="hfeed site">
      <header id="masthead" class="site-header" role="banner">
    <hgroup>
      <h1 class="site-title">
        <a href="/tefuir/" title="南辞的技术博客" rel="home">南辞的技术博客</a>
      </h1>
      
        <h2 class="site-description hitokoto"></h2>
        <script type="text/javascript" src="https://v1.hitokoto.cn/?encode=js"></script>
      
    </hgroup>

    <nav id="site-navigation" class="main-navigation" role="navigation">
            <button class="menu-toggle">菜单</button>
            <a class="assistive-text" href="/#content" title="跳至内容">跳至内容</a><!--TODO-->
            <div class="menu-main-container">
                <ul id="menu-main" class="nav-menu">
                
                    <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="/tefuir/">Home</a></li>
                
                    <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="/tefuir/archives">Archives</a></li>
                
                </ul>
            </div>
    </nav>
</header>

      <div id="main" class="wrapper">
        <div id="primary" class="site-content"><div id="content" role="main"><article id="post-Celery" class="post-Celery post type-post status-publish format-standard hentry">
    <!---->

      <header class="entry-header">
        
        
  
    <h1 class="entry-title article-title">
      Celery
    </h1>
  

        
        <div class="comments-link">
            
            <a href="javascript:void(0);" data-url="https://yanlidoushikeke.gitee.io/myhexo/2021/03/10/Celery/" data-id="ckm3hv60k000064u00cnp3tym" class="leave-reply bdsharebuttonbox" data-cmd="more">Share</a>
        </div><!-- .comments-link -->
      </header><!-- .entry-header -->

    <div class="entry-content">
      
        <h2 id="异步处理Celery"><a href="#异步处理Celery" class="headerlink" title="异步处理Celery"></a>异步处理Celery</h2><p>为什么要使用异步<br>首先，我们要知道计算机的处理分为两种，CPU处理和IO处理。一般来说，处理一个任务，需要CPU和IO相互协调。</p>
<p>CPU的处理速度远远快于IO的，所以当一个任务的CPU处理部分完成后，还需要等待IO的完成。这个等待的过程也就是进程阻塞。进程占着CPU空等没活干。</p>
<p>而异步就是把进程在等待过程中占用的CPU释放掉，让它去处理其他的东西。那正在处理的IO怎么办？系统提供了一种通知机制，使得在IO处理完成后通知系统，该进程进入就绪队列，等待CPU分配。</p>
<p>所以异步使得CPU资源得以充分使用。</p>
<p>一、Celery简介<br>Celery 是一个基于 Python 开发的分布式异步消息任务队列，通过它可以轻松的实现任务的异步处理，</p>
<p>Celery使用场景<br>▷ 异步任务：解放CPU，将耗时的IO任务交给Celery去异步执行，比如发送邮件、音频处理</p>
<p>▷ 定时任务：类似于crontab，比如每日数据统计</p>
<p>Celery构架</p>
<p>▶ Producer：任务委托方</p>
<p>▶ Broker：任务中心（中介），如RabbitMQ、Redis等1</p>
<p>▶ Beat：任务调度器</p>
<p>▶ Worker：任务执行者，可以有多个（分布式）</p>
<p>▶ Result：任务中心的数据库，储存任务执行结果2</p>
<p>▶ Backend：因为任务经由中介，而非直接委派到Worker手上，所以Producer并不知道任务被委派给了谁，以及任务的完成结果，所以这时候需要一个Backend（理解成手机，通过手机查看任务完成情况）</p>
<h4 id="二、Celery的使用"><a href="#二、Celery的使用" class="headerlink" title="二、Celery的使用"></a>二、Celery的使用</h4><h5 id="第一个Celery程序"><a href="#第一个Celery程序" class="headerlink" title="第一个Celery程序"></a>第一个Celery程序</h5><p>新建一个<code>task.py</code></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">from celery import Celery</span><br><span class="line"> </span><br><span class="line">app &#x3D; Celery(&#39;add_task&#39;,</span><br><span class="line">             broker&#x3D;&#39;redis:&#x2F;&#x2F;localhos:6379&#x2F;1&#39;,</span><br><span class="line">             backend&#x3D;&#39;redis:&#x2F;&#x2F;localhost:6379&#x2F;2&#39;) </span><br><span class="line">            </span><br><span class="line">@app.task</span><br><span class="line">def add(x, y):</span><br><span class="line">    print(&quot;running...&quot;,x,y)</span><br><span class="line">    return x+y</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>确定Redis服务已经开启</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">redis-server</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>启动 Celery Worker 来开始监听并执行任务</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">celery -A tasks worker -l info</span><br><span class="line"></span><br><span class="line"># -A 参数表示app名称，-l 参数表示日志类型</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>好了，现在任务给定了，Workers也已经就绪，再新建一个<code>test.py</code>文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">from task import add</span><br><span class="line"></span><br><span class="line">result &#x3D; add.delay(2, 3)    # 提交任务，返回任务id</span><br><span class="line">print(result.ready())    # 返回True的话，表示提交成功</span><br><span class="line">print(result.get())    # 获取任务执行结果</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<h5 id="Celery配置"><a href="#Celery配置" class="headerlink" title="Celery配置"></a>Celery配置</h5><p>从上面的例子可以看出，每次创建app都需要指定broker和backend。<br>怎样简化这个过程呢？</p>
<p>我们可以将相关的文件模块化（模块名celery_app，再添加<strong>init</strong>.py文件）</p>
<p>模块下新建一个<code>celeryconfig.py</code>文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">BROKER_URL &#x3D; &#39;redis:&#x2F;&#x2F;localhos:6379&#x2F;1&#39;</span><br><span class="line"></span><br><span class="line">CELERY_RESULT_BACKEND &#x3D; &#39;redis:&#x2F;&#x2F;localhost:6379&#x2F;2&#39;)</span><br><span class="line"></span><br><span class="line"># 导入指定的任务模块</span><br><span class="line">CELERY_TASKS &#x3D; &#123;</span><br><span class="line">	&#39;celery_app.task1&#39;,    # task1.py是模块下的任务文件</span><br><span class="line">	&#39;celery_app.task2&#39;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>


<p><strong>init</strong>.py</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">from celery import Celery</span><br><span class="line"></span><br><span class="line">app &#x3D; Celery(&#39;demo&#39;)</span><br><span class="line"></span><br><span class="line">app.config_from_object(&#39;celery_app.celeryconfig&#39;)</span><br><span class="line"></span><br></pre></td></tr></table></figure>


<p>以上配置完成后，则在task1.py等文件（存在@app.task）中添加一行，即可</p>
<p>from celery_app import app<br>————————————————<br>版权声明：本文为CSDN博主「一剑何风情」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。<br>原文链接：<a target="_blank" rel="noopener" href="https://blog.csdn.net/weixin_37641832/article/details/83218748">https://blog.csdn.net/weixin_37641832/article/details/83218748</a></p>

      
    </div><!-- .entry-content -->

    <footer class="entry-meta">
    <a href="/tefuir/2021/03/10/Celery/">
    <time datetime="2021-03-10T13:35:14.000Z" class="entry-date">
        2021-03-10
    </time>
</a>
    
    
    </footer>
</article>


    
<nav class="nav-single">
    <h3 class="assistive-text">文章导航</h3>
    
        <span class="nav-previous"><a href="/tefuir/2021/03/11/%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/" rel="prev"><span class="meta-nav">←</span> 权限管理</a></span>
    
    
        <span class="nav-next"><a href="/tefuir/2021/03/03/docker%E5%91%BD%E4%BB%A4/" rel="next">docker命令 <span class="meta-nav">→</span></a></span>
    
</nav><!-- .nav-single -->







</div></div>
        <div id="secondary" class="widget-area" role="complementary">
  
    <aside id="search" class="widget widget_search"><form role="search" method="get" accept-charset="utf-8" id="searchform" class="searchform" action="//google.com/search">
    <div>
        <input type="text" value="" name="s" id="s" />
        <input type="submit" id="searchsubmit" value="搜索" />
    </div>
</form></aside>
  
    
  
    
  
    
  <aside class="widget">
    <h3 class="widget-title">Recents</h3>
    <div class="widget-content">
      <ul>
        
          <li>
            <a href="/tefuir/2021/04/26/python%E5%9F%BA%E7%A1%80%E7%90%86%E8%AE%BA%E5%AE%9D%E5%85%B8/">python基础理论宝典</a>
          </li>
        
          <li>
            <a href="/tefuir/2021/04/23/python3-Flask%E7%BB%93%E5%90%88Socket-io%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%E5%9C%A8%E7%BA%BF%E5%AE%A2%E6%9C%8D%E7%B3%BB%E7%BB%9F/">python3+Flask结合Socket.io简单实现在线客服系统</a>
          </li>
        
          <li>
            <a href="/tefuir/2021/04/23/win10%E7%B3%BB%E7%BB%9F%E4%B8%8B%E5%88%A9%E7%94%A8docker%E9%83%A8%E7%BD%B2gunicorn-Flask%E6%89%93%E9%80%A0%E7%8B%AC%E7%AB%8B%E9%95%9C%E5%83%8F/">win10系统下利用docker部署gunicorn+Flask打造独立镜像</a>
          </li>
        
          <li>
            <a href="/tefuir/2021/04/23/win10%E7%B3%BB%E7%BB%9F%E4%B8%8B%E5%9F%BA%E4%BA%8Edocker%E9%85%8D%E7%BD%AEelasticsearch%E9%85%8D%E5%90%88python3%E8%BF%9B%E8%A1%8C%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2/">win10系统下基于docker配置elasticsearch配合python3进行全文检索</a>
          </li>
        
          <li>
            <a href="/tefuir/2021/04/23/%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%97%AE%E9%A2%98/">服务器问题</a>
          </li>
        
      </ul>
    </div>
  </aside>

  
    
  
    
  
</div>
      </div>
      <footer id="colophon" role="contentinfo">
    <p>&copy; 2021 南辞
    All rights reserved.</p>
    <p>Powered by <a href="http://hexo.io/" target="_blank">Hexo</a></p>
</footer>
    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"1","bdMiniList":false,"bdPic":"","bdStyle":"2","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='/js/share.js'];</script>

<script src="/js/jquery-3.3.1.min.js"></script>


  
<link rel="stylesheet" href="/tefuir/fancybox/jquery.fancybox.css">

  
<script src="/tefuir/fancybox/jquery.fancybox.pack.js"></script>




<script src="/tefuir/js/script.js"></script>


<script src="/js/navigation.js"></script>

<div id="bg"></div>

  </div>
</body>
</html>